package com.mbengue.corp.artisan.dao.impl;

import java.util.Arrays;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.util.Assert;

import com.mbengue.corp.artisan.dao.ArticleDao;
import com.mbengue.corp.artisan.modele.Article;

public class ArticleDaoImpl implements ArticleDao {
  private static Logger logger = Logger.getLogger(ArticleDao.class);
  private HibernateTemplate hbTemplate;

  public void setSessionFactory(SessionFactory sessionFactory) {
    this.hbTemplate = new HibernateTemplate(sessionFactory);
  }

  @Override
  public void ajouterArticle(Article article) throws DataAccessException {
    logger.info("Ajout d'un nouvel article: " + article);
    this.hbTemplate.saveOrUpdate(article);
  }

  @Override
  public void modifierArticle(Article article) throws DataAccessException {
    logger.info("Mise a jour de l'article: " + article);
    this.hbTemplate.update(article);
  }

  @Override
  public void supprimerArticle(Article article) throws DataAccessException {
    logger.info("Article a supprimer: " + article);
    this.hbTemplate.delete(article);
  }

  @SuppressWarnings("unchecked")
  @Override
  public List<Article> tousLesArticles() throws DataAccessException {
    logger.info("Recupere tous les articles");
    DetachedCriteria criteria = DetachedCriteria.forClass(Article.class);
    return this.hbTemplate.findByCriteria(criteria);
  }

  @Override
  public Article trouverArticleParCode(String code) throws DataAccessException {
    logger.info("Trouve l'article dont le code est " + code);
    List<Article> articles = this.trouverArticlesParCode(code);
    Assert.isTrue(articles.size() <= 1);

    if (articles.size() == 0) {
      return null;
    }
    return articles.get(0);
  }

  @SuppressWarnings("unchecked")
  @Override
  public List<String> tousLesCodesArticle() throws DataAccessException {
    return this.hbTemplate.find("select code from Article");
  }

  @SuppressWarnings("unchecked")
  @Override
  public String getDesignationArticle(String code) throws DataAccessException {
    List<String> designations = this.hbTemplate.find("select designation from Article where code = ?", code);
    Assert.notNull(designations);
    Assert.isTrue(designations.size() == 1);
    return designations.get(0);
  }

  @SuppressWarnings("unchecked")
  @Override
  public List<Article> tousLesArticles(String[] codes) throws DataAccessException {
    logger.info("Recupere tous les articles dont le code est dans: " + Arrays.toString(codes));
    StringBuilder strBuilder = new StringBuilder();
    strBuilder.append("(");
    for (int i = 0; i < codes.length - 1; i++) {
      strBuilder.append("'" + codes[i] + "'");
      strBuilder.append(",");
    }
    strBuilder.append("'" + codes[codes.length - 1] + "'");
    strBuilder.append(")");

    return this.hbTemplate.find("select a from Article a where code in " + strBuilder.toString());
  }

  @SuppressWarnings("unchecked")
  @Override
  public List<Article> trouverArticlesParCode(String code) throws DataAccessException {
    logger.info("Trouve tous les articles dont le code contient: " + code);
    return this.hbTemplate.findByNamedQuery("trouverArticleParCode", code);
  }
}
